Skip to content

Add __all__ to hand-written modules; simplify __init__.py template#25

Merged
guenp merged 11 commits into
mainfrom
churchill/fix-pdoc-submodule-discovery
Apr 28, 2026
Merged

Add __all__ to hand-written modules; simplify __init__.py template#25
guenp merged 11 commits into
mainfrom
churchill/fix-pdoc-submodule-discovery

Conversation

@splch

@splch splch commented Apr 26, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Add __all__ to each hand-written module (Python best practice for explicit public APIs)
  • Rewrite package_init.py.jinja to use star imports and dynamic __all__ composition from submodule __all__ lists
  • Template shrinks from 69 lines to 17 - module names listed once via Jinja2 loops, all exported symbols derived from the code itself
  • Add public module names to __all__ so pdoc discovers submodule pages with their module-level docstrings

How it works

Each hand-written module declares __all__ (e.g., __all__ = ["SessionManager"]). The template star-imports from each module and composes the package __all__ by unpacking *module.__all__. When a symbol is added to any module's __all__, it automatically appears in the package exports with no template changes needed.

Test plan

  • uv run pytest tests/ - 219 passed, 100% coverage
  • uv run ruff check - clean
  • Regeneration is idempotent (second run produces zero diff)
  • All 39 symbols importable from ionq_core
  • uv run pdoc generates 7 submodule pages with module-level docstrings

splch added 10 commits April 26, 2026 11:14
pdoc uses __all__ to gate which submodules it discovers. Without the
module names in __all__, pdoc only rendered the flat symbol list and
skipped the submodule pages with their module-level docstrings.
Delete the 69-line custom template override. Instead, add __all__ to
each hand-written module (Python best practice) and use a 37-line
post-hook script that reads those declarations via AST to extend the
generated __init__.py. The only hand-maintained list is the 7 module
names; all exported symbols are derived from the code itself.
Use star imports from modules that define __all__ (Python best practice)
and compose __init__.__all__ dynamically from submodule __all__ lists.
Template shrinks from 69 lines to 24 with no external script. All
exported symbols are derived from the code itself.
Module names listed once; Jinja2 generates the imports and __all__
composition. Template shrinks from 24 to 13 lines.
Ruff cannot statically resolve the dynamic __all__ and flags the
explicit imports as unused. Add F401/F403 suppression comments.
Replace set-union with splat unpacking in a single set literal. Fewer
Jinja brace escapes and consistent use of the for-loop pattern.
Collapse __all__ block to single line (ruff reformats the output) and
remove unnecessary blank line.
Consistent whitespace control on all tags, readable __all__ block with
one entry per line, blank line separating imports from __all__.
- Rename mods -> modules (descriptive names, not abbreviations)
- Remove all -%} dash modifiers (trim_blocks and lstrip_blocks are
  enabled in the Environment, making manual trimming unnecessary)
@splch splch changed the title Add public modules to __all__ for pdoc submodule discovery Add __all__ to hand-written modules; simplify __init__.py template Apr 26, 2026
@splch splch self-assigned this Apr 26, 2026

@guenp guenp left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Codex Review

Automated review by OpenAI Codex (gpt-5.4), triggered by @guen-p.

Summary

This PR adds explicit __all__ declarations to all 7 hand-written modules and rewrites the package_init.py.jinja template to use star imports composed from those __all__ lists. The template shrinks from ~69 lines to 17, and adding a new public symbol only requires updating the source module's __all__ — no template changes needed.

Observations

  • Looks correct. Each module's __all__ matches the symbols that were previously imported explicitly in __init__.py. The composed __all__ in the generated __init__.py covers all 39 symbols (verified by the test plan).
  • noqa comments are appropriate. F403 (star imports) and F401 (unused imports) are the right suppressions here since the star imports are controlled by __all__.
  • client and types stay explicit — presumably because they're auto-generated and don't declare __all__. This is the right call.

Minor suggestions

  • __version__ in ionq_client.__all__: Re-exporting a dunder via __all__ is slightly unusual. Consider whether __version__ should live in its own top-level assignment (e.g. in __init__.py directly) rather than being star-imported from ionq_client. Not a blocker — just a style preference.
  • __all__ placement: The __all__ declarations are placed above the imports (e.g. in gates.py, __all__ comes before import cmath). PEP 8 / isort convention typically puts imports first. Consider moving __all__ to just after the imports and module docstring for consistency. Again, not a blocker.

Verdict

Looks good overall — clean simplification with solid test coverage. The two notes above are style nits, not correctness issues. 👍

@guenp guenp left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Codex Review

This is an automated review by Codex (OpenAI).

Summary: this PR adds explicit __all__ lists to the hand-written modules and simplifies __init__.py generation by deriving package exports from those module-level __all__ lists, while also exposing submodule names for pdoc discovery.

  • I did not spot any correctness issues in the export refactor during this light review.
  • Minor suggestion: adding the module objects to package __all__ changes from ionq_core import * semantics slightly, so it may be worth calling that out explicitly as an intentional API/docs tradeoff.
  • If the 39 symbols importable from ionq_core check is not already enforced in the automated test suite, a small regression test would help keep the package export surface stable as modules evolve.

Overall assessment: looks good overall for a light review.

guenp
guenp previously approved these changes Apr 27, 2026

@guenp guenp left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm, I did human + ai review, approved with codex suggestions above!

PEP 8's "Module Level Dunder Names" rule places __all__ after the
docstring but before any non-__future__ imports. The other
hand-written modules already follow this; extensions.py was the
outlier.
@splch

splch commented Apr 27, 2026

Copy link
Copy Markdown
Collaborator Author

Thanks for the thorough review! Addressed one and as for the others:

__all__ placement — moved __all__ before imports in extensions.py for consistency with the other 5 modules (ccde35c). This actually matches PEP 8's "Module Level Dunder Names" rule, which places dunders after the docstring but before any non-__future__ imports. So the fix went the opposite direction from the suggestion — extensions.py was the outlier.

__version__ in ionq_client.__all__ — leaving as-is. Moving it to __init__.py would shift ~6 lines into the template and need either a lazy import or careful ordering to avoid a circular import on package load. Net zero on lines, slightly more fragile, so keeping the dunder re-export.

from ionq_core import * semantics / regression test — the module-name additions are intentional (they're what makes pdoc discover the submodule pages), and the existing test suite already imports every public symbol, so a separate count check would be redundant.

@guenp guenp merged commit 855ece5 into main Apr 28, 2026
10 checks passed
@guenp guenp deleted the churchill/fix-pdoc-submodule-discovery branch April 28, 2026 01:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants